<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@page import="java.security.*,java.net.*,java.io.*"%>
<%@page import="java.lang.StackTraceElement"%>
<%!
  public static URL getClassLocation(final Class cls) {
    if (cls == null)throw new IllegalArgumentException("null input: cls");
    URL result = null;
    final String clsAsResource = cls.getName().replace('.', '/').concat(".class");
    final ProtectionDomain pd = cls.getProtectionDomain();
    // java.lang.Class contract does not specify if 'pd' can ever be null;
    // it is not the case for Sun's implementations, but guard against null
    // just in case:
    if (pd != null) {
      final CodeSource cs = pd.getCodeSource();
      // 'cs' can be null depending on the classloader behavior:
      if (cs != null) result = cs.getLocation();
      if (result != null) {
        // Convert a code source location into a full class file location
        // for some common cases:
        if ("file".equals(result.getProtocol())) {
          try {
            if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) {
              result = new URL("jar: ".concat(result.toExternalForm()).concat("!/").concat(clsAsResource));
            } else if (new File(result.getFile()).isDirectory()) {
              result = new URL(result, clsAsResource);
            }
          }
          catch (MalformedURLException ignore) {}
        }
      }
    }
    if (result == null) {
      // Try to find 'cls' definition as a resource; this is not
      // document．d to be legal, but Sun's implementations seem to         //allow this:
      final ClassLoader clsLoader = cls.getClassLoader();
      result = clsLoader != null ?
          clsLoader.getResource(clsAsResource) :
          ClassLoader.getSystemResource(clsAsResource);
    }
    return result;
  }
%>
<html>
<head>
  <title>`.class` 文件从哪个jar包中加载</title>
  <style type="text/css">
    p {
      text-indent: 2em;
      /*em是相对单位，2em即现在一个字大小的两倍*/
    }
  </style>
</head>
<body bgcolor="#ffffff">
  使用方法，className参数为类的全名，不需要 `.class` 后缀，如: <br>
  findClassFromJar.jsp?className=java.net.URL <br><br>
  <hr>
<%
  try {
    String classLocation;
    String className = request.getParameter("className");

    if(className != null) {
      classLocation =  URLDecoder.decode(getClassLocation(Class.forName(className)).toString());
      out.print("类 " + className + " 实例的物理文件位于：<br>");
      out.print(classLocation);
    } else {
      out.print("请携带参数：");
      out.print("className=java.net.URL");
    }
  } catch(Exception e) {
    out.println("异常堆栈信息：<br><p></p>");
    out.println(e + "<br>");
    StackTraceElement[] trace = e.getStackTrace();
    for (StackTraceElement traceElement : trace) {
      out.println("&nbsp;&nbsp;&nbsp;&nbsp;at " + traceElement + "<br>");
    }
  }
%>
</body>
</html>
